/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * MontajeDesmontaje.java
 *
 * Created on 17-may-2012, 22:57:21
 */
package com.camachosanchez.gui;

import com.camachosanchez.bean.*;
import com.camachosanchez.controler.jdbc.BateriasJdbcControler;
import com.camachosanchez.controler.jdbc.ControlCambioNeumaticoJdbcControler;
import com.camachosanchez.controler.jdbc.NeumaticosJdbcControler;
import com.camachosanchez.controler.jdbc.PilotosJdbcControler;
import com.camachosanchez.controler.jdbc.TalleresJdbcControler;
import com.camachosanchez.controler.jpa.BateriasJpaController;
import com.camachosanchez.gui.table.ModeloTablaMontajeBaterias;
import com.camachosanchez.gui.table.ModeloTablaMontajeDesmontaje;
import com.camachosanchez.gui.table.RenderizadorTablaMontaje;
import com.camachosanchez.gui.table.RenderizadorTablaMontajeBaterias;
import com.camachosanchez.gui.table.TableSorter;
import com.camachosanchez.gui.textfield.MaxLengthTextDocument;
import com.camachosanchez.mechanics.Bateria;
import com.camachosanchez.mechanics.ContenedorBateria;
import com.camachosanchez.mechanics.Eje;
import com.camachosanchez.mechanics.Llanta;
import com.camachosanchez.util.*;
import java.awt.*;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.dnd.DropTargetDragEvent;
import java.awt.dnd.DropTargetDropEvent;
import java.awt.dnd.DropTargetEvent;
import java.awt.dnd.DropTargetListener;
import java.awt.event.*;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.swing.*;
import javax.swing.TransferHandler.TransferSupport;
import javax.swing.event.InternalFrameEvent;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
import javax.swing.text.html.HTMLDocument;
import javax.swing.text.html.HTMLEditorKit;
import net.coderazzi.filters.gui.TableFilterHeader;

/**
 *
 * @author Rolando
 */
public class MontajeDesmontaje extends javax.swing.JInternalFrame /*implements MouseListener*/ {

    private EntityManagerFactory emf = null;
    private int img_x;
    private int img_y;
    private int tipo_vehiculo;
    private int id_llanta_agregada;
    private int id_bateria_agregada;
    private int draggedPoint;
    private int draggedPointBateria;
    private int xAnteriorRaton = 0; //x en la que estaba anteriormente el ratón.
    private int yAnteriorRaton = 0; //y en la que estaba anteriormente el ratón.
    private int contador;
    private boolean arrastra;
    private boolean arrastraBateria;
    private boolean entro;
    private String descripcion;
    private Point centro;
    private Point point_screen;
    private Image imagen;
    private List<Llanta> llantas_iniciales;
    private List<Llanta> llantas_finales;
    private List<Llanta> llantas_observadas;
    private List<Bateria> baterias_iniciales;
    private List<Bateria> baterias_finales;
    private List<Eje> ejes;
    private List<ContenedorBateria> contBaterias;
    private List<Neumaticos> neumaticos;
    private List<Baterias> baterias;
    private Lienzo lienzo;
    //private LienzoBaterias lienzoBaterias;
    private Vehiculos vehiculo;
    private JComboBox comboPilotos;
    private JComboBox comboTalleres;
    private ModeloTablaMontajeDesmontaje modelo;
    private ModeloTablaMontajeBaterias modeloBaterias;
    private RenderizadorTablaMontaje render;
    private RenderizadorTablaMontajeBaterias renderBaterias;
    private Llanta llanta_arrastrada;
    private Llanta llanta_seleccionada;
    private Eje eje_seleccionado;
    private Bateria bateria_arrastrada;
    private Bateria bateria_seleccionada;
    private ContenedorBateria contBateria_seleccionado;
    private JPopupMenu popmenu;
    private JPopupMenu popmenuBaterias;
//    private TableSorter tableSorter;
    private TableFilterHeader filterHeader;
    private TableFilterHeader filterHeaderBaterias;
    private JWindow toolTip;
    private JLabel label;
    private Timer timer;
    private int idNeumaticoResaltado = -1;
    private int idBateriaResaltada = -1;
    private int posX = 0;
    private int posY = 0;
    private int w_img = 0;
    private int h_img = 0;
    private boolean posiciones = false;
    private List<String> tablaInformacion;
    private List<String> tablaInformacionBaterias;
    private int nroBaterias = 0;
    private int anchoB = 80;
    private int altoB = 50;
    
    private boolean mostrarNeumaticosPos = true;
    private JEditorPane html = null;
    
    /**
     * Creates new form MontajeDesmontaje
     */
    public MontajeDesmontaje(Vehiculos vehiculo) {
        tablaInformacion = new ArrayList<String>();
        tablaInformacionBaterias = new ArrayList<String>();
        inicializarGUI();
        this.emf = JPAUtil.getEntityManagerFactory();
        this.id_llanta_agregada = -1;
        this.llantas_finales = new ArrayList<Llanta>();
        this.llantas_iniciales = new ArrayList<Llanta>();
        this.llantas_observadas = new ArrayList<Llanta>();
        this.id_bateria_agregada = -1;
        this.baterias_finales = new ArrayList<Bateria>();
        this.baterias_iniciales = new ArrayList<Bateria>();
        this.vehiculo = vehiculo;
        this.imagen = null;
        this.tipo_vehiculo = 0;
        this.draggedPoint = -1;
        this.draggedPointBateria = -1;
        this.contador = 0;
        this.modelo = new ModeloTablaMontajeDesmontaje();
        this.modeloBaterias = new ModeloTablaMontajeBaterias();
        this.entro = false;
        this.arrastra = false;
        this.arrastraBateria = false;
        this.llanta_arrastrada = null;
        this.llanta_seleccionada = null;
        this.eje_seleccionado = null;
        this.bateria_arrastrada = null;
        this.bateria_seleccionada = null;
        this.contBateria_seleccionado = null;
        this.descripcion = "";
        this.nroBaterias = vehiculo.getNroBaterias();
        render = new RenderizadorTablaMontaje();
        renderBaterias = new RenderizadorTablaMontajeBaterias();
        tablaLlantas.setDefaultRenderer(String.class, render);
        tablaBaterias.setDefaultRenderer(String.class, renderBaterias);
        inicializarImagenes();
        TableSorter tableSorter = new TableSorter(modelo, tablaLlantas.getTableHeader());
        tablaLlantas.setModel(tableSorter);
        filterHeader = new TableFilterHeader();
        filterHeader.setTable(tablaLlantas);
        tablaLlantas.getTableHeader().setReorderingAllowed(false);
        TableSorter tableSorterBaterias = new TableSorter(modeloBaterias, tablaBaterias.getTableHeader());
        tablaBaterias.setModel(tableSorterBaterias);
        filterHeaderBaterias = new TableFilterHeader();
        filterHeaderBaterias.setTable(tablaBaterias);
        tablaBaterias.getTableHeader().setReorderingAllowed(false);
        if (imagen != null) {
            llenarTabla();
            //BATERIASSSS
            llenarTablaBaterias();
        }
        this.setMinimumSize(new Dimension(1100, 600));
        setFrameIcon(new ImageIcon(getClass().getResource("/com/camachosanchez/recursos/table.png")));
        GUIUtil.fondoBarraHerramientas(jToolBar1);
//        tablaInformacion.add("Número de placa:¬" + vehiculo.getPlaca());
//        tablaInformacion.add("Tipo de unidad:¬" + vehiculo.getPlaca());
//        tablaInformacion.add("Modelo de chasis:¬" + vehiculo.getIdTipoEje().getNombre());
        this.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
        this.addInternalFrameListener(new javax.swing.event.InternalFrameAdapter() {

            @Override
            public void internalFrameClosing(InternalFrameEvent e) {
                cerrar();
            }
        });
        
        dateFechaMontaje.setDate(new Date());
        //BATERÍASSSS
        //jScrollPane3.setVisible(false);
    }

    private void cerrar() {
        GUIUtil.maximizarTodasLasVentanas(this);
    }

    public void setIdNeumaticoResaltado(int idNeumaticoResaltado) {
        this.idNeumaticoResaltado = idNeumaticoResaltado;
    }

    public void setIdBateriaResaltada(int idBateriaResaltada) {
        this.idBateriaResaltada = idBateriaResaltada;
    }
    
    private boolean agregado(Neumaticos neumatico) {
        for (Llanta llanta : llantas_finales) {
            if (llanta.getIdNeumatico() == neumatico.getId()) {
                return true;
            }
        }
        return false;
    }

    private void setAnchoColumnas() {
        int anchoColumna;
        TableColumnModel modeloColumna = tablaLlantas.getColumnModel();
        TableColumn columnaTabla;
        for (int i = 0; i < tablaLlantas.getColumnCount(); i++) {
            columnaTabla = modeloColumna.getColumn(i);
            switch (i) {
                case 4:
                    anchoColumna = 0;
                    columnaTabla.setMinWidth(anchoColumna);
                    columnaTabla.setMaxWidth(anchoColumna);
                    columnaTabla.setPreferredWidth(anchoColumna);
                    break;
            }
        }
    }
    
    private void setColumnaOcultaBaterias() {
        int anchoColumna;
        TableColumnModel modeloColumna = tablaBaterias.getColumnModel();
        TableColumn columnaTabla;
        for (int i = 0; i < tablaBaterias.getColumnCount(); i++) {
            columnaTabla = modeloColumna.getColumn(i);
            switch (i) {
                case 0:
                    anchoColumna = 0;
                    columnaTabla.setMinWidth(anchoColumna);
                    columnaTabla.setMaxWidth(anchoColumna);
                    columnaTabla.setPreferredWidth(anchoColumna);
                    break;
            }
        }
    }

    private void llenarTabla() {
        modelo.limpiar();
        try {
            for (Neumaticos neumatico : neumaticos) {
                modelo.agregarNeumatico(neumatico, -1);
            }
        } catch (Exception e) {
            JOptionPane.showMessageDialog(Principal.getInstance(), e.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
        }
        GUIUtil.SetAnchoColumnas(tablaLlantas);
        setAnchoColumnas();
    }

    private void llenarTablaBaterias() {
        modeloBaterias.limpiar();
        try {
            for (Baterias bateria : baterias) {
                modeloBaterias.agregarBateria(bateria, -1);
            }
        } catch (Exception e) {
            JOptionPane.showMessageDialog(Principal.getInstance(), e.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
        }
        GUIUtil.SetAnchoColumnas(tablaBaterias);
        setColumnaOcultaBaterias();
    }
    
    private void inicializarGUI() {
        try {
            initComponents();
            MaxLengthTextDocument doc_kilometros = new MaxLengthTextDocument();
            doc_kilometros.setMaxChars(20, Constantes.DECIMALES);
            txtKilometraje.setDocument(doc_kilometros);
            txtKilometraje.setText("0.0");
            popmenu = new JPopupMenu();
            popmenuBaterias = new JPopupMenu();
            PilotosJdbcControler daoJdbcP = new PilotosJdbcControler();
            TalleresJdbcControler daoJdbcT = new TalleresJdbcControler();
            comboPilotos = new JComboBox(new DefaultComboBoxModel(daoJdbcP.findAll().toArray()));
            comboTalleres = new JComboBox(new DefaultComboBoxModel(daoJdbcT.findAll().toArray()));
            panelPilotos.add(comboPilotos, BorderLayout.CENTER);
            panelPatios.add(comboTalleres, BorderLayout.CENTER);
            lienzo = new Lienzo();
            lienzo.revalidate();
            cotenedor.add(lienzo, BorderLayout.CENTER);
//            lienzoBaterias = new LienzoBaterias(jPanelBaterias.getWidth(), jPanelBaterias.getHeight(), modeloBaterias, tablaBaterias);
//            lienzoBaterias.revalidate();
//            jPanelBaterias.add(lienzoBaterias, BorderLayout.CENTER);
            NeumaticosJdbcControler daoJdbc = new NeumaticosJdbcControler();
            neumaticos = daoJdbc.findNeumaticosStock();
            tablaLlantas.setDragEnabled(true);
            BateriasJdbcControler daoBateriasJdbc = new BateriasJdbcControler();
            baterias = daoBateriasJdbc.findBateriasStock();
            tablaBaterias.setDragEnabled(true);
            lienzo.setTransferHandler(new TransferHandler() {

                @Override
                public boolean canImport(TransferSupport support) {
                    if (!support.isDrop()) {
                        return false;
                    }
                    if (!support.isDataFlavorSupported(DataFlavor.stringFlavor)) {
                        return false;
                    }
                    return true;
                }

                @Override
                public boolean importData(TransferSupport support) {
                    if (!canImport(support)) {
                        return false;
                    }
                    String llanta_agregada;
                    try {
                        llanta_agregada = (String) support.getTransferable().getTransferData(DataFlavor.stringFlavor);
                        String tokens[] = llanta_agregada.split("\t");
                        if (tokens.length == 6) {
                            id_llanta_agregada = Integer.parseInt(tokens[4]);
                        } else if (tokens.length == 5) {
                            id_bateria_agregada = Integer.parseInt(tokens[0]);
                        }
                    } catch (UnsupportedFlavorException e) {
                        JOptionPane.showMessageDialog(Principal.getInstance(), e.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
                        return false;
                    } catch (IOException e) {
                        JOptionPane.showMessageDialog(Principal.getInstance(), e.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
                        return false;
                    }
                    return true;
                }
            });
            lienzo.getDropTarget().addDropTargetListener(new DropTargetListener() {

                @Override
                public void dragOver(DropTargetDragEvent e) {
                }

                @Override
                public void dragEnter(DropTargetDragEvent e) {
                }

                @Override
                public void dragExit(DropTargetEvent e) {
                }

                @Override
                public void drop(DropTargetDropEvent e) {
                    if (id_llanta_agregada != -1) {
                        for (Eje eje : ejes) {
                            if (eje.estaDentro(e.getLocation()) && !eje.isEstaMontado()) {
                                eje.setEstaMontado(true);
                                Llanta llanta = new Llanta(eje, id_llanta_agregada, lienzo.getWidth(), lienzo.getHeight());
                                //verificar el origen de la bateria
                                //--------------------------------
                                for (Llanta tire : llantas_iniciales) {
                                    if (tire.getIdNeumatico() == id_llanta_agregada) {
                                        llanta.setOrigen(Constantes.FROM_DB);
                                        llanta.setCodigo(tire.getCodigo());
                                        break;
                                    }
                                }
                                //--------------------------------
                                llantas_finales.add(llanta);
                                modelo.borrarLlanta(tablaLlantas.getSelectedRow());
                                break;
                            }
                        }
                        id_llanta_agregada = -1;
                        pintarPosiciones();
                        lienzo.repaint();
                    }
                    
                    if (id_bateria_agregada != -1) {
                        for (ContenedorBateria cont : contBaterias) {
                            if (cont.estaDentro(e.getLocation()) && !cont.isEstaMontado()) {
                                cont.setEstaMontado(true);
                                Bateria bateria = new Bateria(cont, id_bateria_agregada, lienzo.getWidth(), lienzo.getHeight());
                                //verificar el origen de la bateria
                                //--------------------------------
                                for (Bateria b : baterias_iniciales) {
                                    if (b.getIdBateria() == id_bateria_agregada) {
                                        bateria.setOrigen(Constantes.FROM_DB);
                                        bateria.setCodigo(b.getCodigo());
                                        break;
                                    }
                                }
                                //--------------------------------
                                baterias_finales.add(bateria);
                                modeloBaterias.borrarBateria(tablaBaterias.getSelectedRow());
                                break;
                            }
                        }
                        id_bateria_agregada = -1;
                        pintarPosiciones();
                        lienzo.repaint();
                    }
                }

                @Override
                public void dropActionChanged(DropTargetDragEvent e) {
                }
            });
            lienzo.addMouseListener(lienzo);
            lienzo.addMouseMotionListener(lienzo);
            lienzo.add(popmenu);
            lienzo.add(popmenuBaterias);
            JMenuItem desmontar_menu = new JMenuItem("Desmontar");
            JMenuItem desmontar_emergencia = new JMenuItem("Desmontaje en carretera");
            JMenuItem reencauche_menu = new JMenuItem("Para reencauche");
            JMenuItem reparacion_menu = new JMenuItem("Para reparación");
            JMenuItem cementerio_menu = new JMenuItem("Enviar a cementerio");
            JMenuItem bodega_menu = new JMenuItem("Enviar a bodega");
            desmontar_menu.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/camachosanchez/recursos/arrow_right.png")));
            desmontar_emergencia.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/camachosanchez/recursos/warning.png")));
            reencauche_menu.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/camachosanchez/recursos/reencauche.png")));
            reparacion_menu.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/camachosanchez/recursos/reparacion.png")));
            cementerio_menu.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/camachosanchez/recursos/cementerio.png")));
            bodega_menu.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/camachosanchez/recursos/bodega.png")));
            popmenu.add(desmontar_menu);
            popmenu.add(new JSeparator());
            popmenu.add(reencauche_menu);
            popmenu.add(reparacion_menu);
            popmenu.add(new JSeparator());
            popmenu.add(cementerio_menu);
            popmenu.add(bodega_menu);
            popmenu.add(new JSeparator());
            popmenu.add(desmontar_emergencia);
            bodega_menu.addActionListener(new ActionListener() {

                @Override
                public void actionPerformed(ActionEvent e) {
                    try {
                        if (llanta_seleccionada != null) {
                            llanta_seleccionada.getEje().setEstaMontado(false);
                            llantas_finales.remove(llanta_seleccionada);
                            int pos = indiceDe(llanta_seleccionada, llantas_iniciales);
                            if (pos >= 0) {
                                llanta_seleccionada.setIdCategoria(Constantes.CATEGORIA_BODEGA);
                                llantas_iniciales.set(pos, llanta_seleccionada);
                            }
                            lienzo.repaint();
                            NeumaticosJdbcControler dao = new NeumaticosJdbcControler();
                            Neumaticos neumaticoTemporal = dao.findNeumatico(llanta_seleccionada.getIdNeumatico());
                            neumaticoTemporal.setIdCategoria(new Categorias(Constantes.CATEGORIA_BODEGA));
                            modelo.agregarNeumatico(neumaticoTemporal, 0);//agrega al inicio de la tabla
                            llanta_seleccionada = null;
//                            llenarTabla("");
                        }
                    } catch (Exception ex) {
                        JOptionPane.showMessageDialog(Principal.getInstance(), ex.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
                    }
                }
            });
            cementerio_menu.addActionListener(new ActionListener() {

                @Override
                public void actionPerformed(ActionEvent e) {
                    try {
                        if (llanta_seleccionada != null) {
                            llanta_seleccionada.getEje().setEstaMontado(false);
                            llantas_finales.remove(llanta_seleccionada);
                            int pos = indiceDe(llanta_seleccionada, llantas_iniciales);
                            if (pos >= 0) {
                                llanta_seleccionada.setIdCategoria(Constantes.CATEGORIA_CEMENTERIO);
                                llantas_iniciales.set(pos, llanta_seleccionada);
                            }
                            lienzo.repaint();
                            NeumaticosJdbcControler dao = new NeumaticosJdbcControler();
                            Neumaticos neumaticoTemporal = dao.findNeumatico(llanta_seleccionada.getIdNeumatico());
                            neumaticoTemporal.setIdCategoria(new Categorias(Constantes.CATEGORIA_CEMENTERIO));
                            modelo.agregarNeumatico(neumaticoTemporal, 0);//agrega al inicio de la tabla
                            llanta_seleccionada = null;
//                            llenarTabla("");
                        }
                    } catch (Exception ex) {
                        JOptionPane.showMessageDialog(Principal.getInstance(), ex.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
                    }
                }
            });
            reparacion_menu.addActionListener(new ActionListener() {

                @Override
                public void actionPerformed(ActionEvent e) {
                    try {
                        if (llanta_seleccionada != null) {
                            llanta_seleccionada.getEje().setEstaMontado(false);
                            llantas_finales.remove(llanta_seleccionada);
                            int pos = indiceDe(llanta_seleccionada, llantas_iniciales);
                            if (pos >= 0) {
                                llanta_seleccionada.setIdCategoria(Constantes.CATEGORIA_REPARACION);
                                llantas_iniciales.set(pos, llanta_seleccionada);
                            }
                            lienzo.repaint();
                            NeumaticosJdbcControler dao = new NeumaticosJdbcControler();
                            Neumaticos neumaticoTemporal = dao.findNeumatico(llanta_seleccionada.getIdNeumatico());
                            neumaticoTemporal.setIdCategoria(new Categorias(Constantes.CATEGORIA_REPARACION));
                            modelo.agregarNeumatico(neumaticoTemporal, 0);//agrega al inicio de la tabla
                            llanta_seleccionada = null;
//                            llenarTabla("");
                        }
                    } catch (Exception ex) {
                        JOptionPane.showMessageDialog(Principal.getInstance(), ex.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
                    }
                }
            });
            desmontar_menu.addActionListener(new ActionListener() {

                @Override
                public void actionPerformed(ActionEvent e) {
                    try {
                        if (llanta_seleccionada != null) {
                            llanta_seleccionada.getEje().setEstaMontado(false);
                            llantas_finales.remove(llanta_seleccionada);
                            int pos = indiceDe(llanta_seleccionada, llantas_iniciales);
                            if (pos >= 0) {
                                llanta_seleccionada.setIdCategoria(Constantes.CATEGORIA_STOCK);//Stock
                                llantas_iniciales.set(pos, llanta_seleccionada);
                            }
                            lienzo.repaint();
                            NeumaticosJdbcControler dao = new NeumaticosJdbcControler();
                            Neumaticos neumaticoTemporal = dao.findNeumatico(llanta_seleccionada.getIdNeumatico());
                            neumaticoTemporal.setIdCategoria(new Categorias(Constantes.CATEGORIA_MONTADO));
                            modelo.agregarNeumatico(neumaticoTemporal, 0);//agrega al inicio de la tabla
                            llanta_seleccionada = null;
//                            llenarTabla("");
                        }
                    } catch (Exception ex) {
                        JOptionPane.showMessageDialog(Principal.getInstance(), ex.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
                    }
                }
            });
            desmontar_emergencia.addActionListener(new ActionListener() {

                @Override
                public void actionPerformed(ActionEvent e) {
                    try {
                        if (llanta_seleccionada != null) {
                            if (llanta_seleccionada.getOrigen() == Constantes.FROM_DB) {
                                DialogoIngresoEgreso dlgEgreso = new DialogoIngresoEgreso(Principal.getInstance(), true);
                                dlgEgreso.setVisible(true);
                                String valor = dlgEgreso.obtenerMonto();
                                if (dlgEgreso.getReturnStatus() == DialogoIngresoEgreso.RET_OK) {
                                    //------------------------------------------------------------
                                    Llanta llantaConEgreso = existeEgresoRegistrado(llanta_seleccionada, llantas_observadas);
                                    Double valorPagado = 0d;
                                    try {
                                        valorPagado = Double.parseDouble(valor);
                                    } catch (Exception ex) {
                                        valorPagado = 0d;
                                    }
                                    if (llantaConEgreso != null) {
                                        llantaConEgreso.getEgreso().setMonto(new BigDecimal(valorPagado));
                                    } else {
                                        Llanta llantaObservada = (Llanta) llanta_seleccionada.clone();
                                        Egresos re = new Egresos();
                                        re.setMonto(new BigDecimal(valorPagado));
                                        llantaObservada.setEgreso(re);
                                        llantas_observadas.add(llantaObservada);
                                    }
                                    //------------------------------------------------------------
                                    llanta_seleccionada.getEje().setEstaMontado(false);
                                    llantas_finales.remove(llanta_seleccionada);
                                    int pos = indiceDe(llanta_seleccionada, llantas_iniciales);
                                    if (pos >= 0) {
                                        llanta_seleccionada.setIdCategoria(Constantes.CATEGORIA_STOCK);//Stock
                                        llantas_iniciales.set(pos, llanta_seleccionada);
                                    }
                                    lienzo.repaint();
                                    NeumaticosJdbcControler dao = new NeumaticosJdbcControler();
                                    Neumaticos neumaticoTemporal = dao.findNeumatico(llanta_seleccionada.getIdNeumatico());
                                    neumaticoTemporal.setIdCategoria(new Categorias(Constantes.CATEGORIA_MONTADO));
                                    modelo.agregarNeumatico(neumaticoTemporal, 0);//agrega al inicio de la tabla
                                    llanta_seleccionada = null;
                                }
                            }
                        }
                    } catch (Exception ex) {
                        JOptionPane.showMessageDialog(Principal.getInstance(), ex.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
                    }
                }

                private Llanta existeEgresoRegistrado(Llanta llanta_seleccionada, List<Llanta> llantas_observadas) {
                    for (Llanta llanta : llantas_observadas) {
                        if (llanta.getIdNeumatico() == llanta_seleccionada.getIdNeumatico()) {
                            return llanta;
                        }
                    }
                    return null;
                }
            });
            reencauche_menu.addActionListener(new ActionListener() {

                @Override
                public void actionPerformed(ActionEvent e) {
                    try {
                        if (llanta_seleccionada != null) {
                            llanta_seleccionada.getEje().setEstaMontado(false);
                            llantas_finales.remove(llanta_seleccionada);
                            int pos = indiceDe(llanta_seleccionada, llantas_iniciales);
                            if (pos >= 0) {
                                llanta_seleccionada.setIdCategoria(Constantes.CATEGORIA_PARA_REENCAUCHE);
                                llantas_iniciales.set(pos, llanta_seleccionada);
                            }
                            lienzo.repaint();
                            NeumaticosJdbcControler dao = new NeumaticosJdbcControler();
                            Neumaticos neumaticoTemporal = dao.findNeumatico(llanta_seleccionada.getIdNeumatico());
                            neumaticoTemporal.setIdCategoria(new Categorias(Constantes.CATEGORIA_PARA_REENCAUCHE));
                            modelo.agregarNeumatico(neumaticoTemporal, 0);//agrega al inicio de la tabla
                            llanta_seleccionada = null;
//                            llenarTabla("");
                        }
                    } catch (Exception ex) {
                        JOptionPane.showMessageDialog(Principal.getInstance(), ex.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
                    }
                }
            });

            JMenuItem desmontar_menuB = new JMenuItem("Desmontar");
            JMenuItem reparacion_menuB = new JMenuItem("Para reparación");
            JMenuItem cementerio_menuB = new JMenuItem("Enviar a cementerio");
            JMenuItem bodega_menuB = new JMenuItem("Enviar a bodega");
            desmontar_menuB.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/camachosanchez/recursos/arrow_right.png")));
            reparacion_menuB.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/camachosanchez/recursos/reparacion.png")));
            cementerio_menuB.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/camachosanchez/recursos/cementerio.png")));
            bodega_menuB.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/camachosanchez/recursos/bodega.png")));
            popmenuBaterias.add(desmontar_menuB);
            popmenuBaterias.add(new JSeparator());
            popmenuBaterias.add(reparacion_menuB);
            popmenuBaterias.add(bodega_menuB);
            popmenuBaterias.add(cementerio_menuB);
            
            desmontar_menuB.addActionListener(new ActionListener() {

                @Override
                public void actionPerformed(ActionEvent e) {
                    try {
                        if (bateria_seleccionada != null) {
                            bateria_seleccionada.getContenedor().setEstaMontado(false);
                            baterias_finales.remove(bateria_seleccionada);
                            int pos = indiceDe(bateria_seleccionada, baterias_iniciales);
                            if (pos >= 0) {
                                bateria_seleccionada.setIdCategoria(Constantes.CATEGORIA_STOCK);//Stock
                                baterias_iniciales.set(pos, bateria_seleccionada);
                            }
                            lienzo.repaint();
                            BateriasJpaController dao = new BateriasJpaController(null);
                            Baterias bateriaTemporal = dao.findBaterias(bateria_seleccionada.getIdBateria());
                            bateriaTemporal.setIdCategoria(new Categorias(Constantes.CATEGORIA_MONTADO));
                            modeloBaterias.agregarBateria(bateriaTemporal, 0);//agrega al inicio de la tabla
                            bateria_seleccionada = null;
                        }
                    } catch (Exception ex) {
                        JOptionPane.showMessageDialog(Principal.getInstance(), ex.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
                    }
                }
            });
            
            bodega_menuB.addActionListener(new ActionListener() {

                @Override
                public void actionPerformed(ActionEvent e) {
                    try {
                        if (bateria_seleccionada != null) {
                            bateria_seleccionada.getContenedor().setEstaMontado(false);
                            baterias_finales.remove(bateria_seleccionada);
                            int pos = indiceDe(bateria_seleccionada, baterias_iniciales);
                            if (pos >= 0) {
                                bateria_seleccionada.setIdCategoria(Constantes.CATEGORIA_BODEGA);
                                baterias_iniciales.set(pos, bateria_seleccionada);
                            }
                            lienzo.repaint();
                            BateriasJpaController dao = new BateriasJpaController(null);
                            Baterias bateriaTemporal = dao.findBaterias(bateria_seleccionada.getIdBateria());
                            bateriaTemporal.setIdCategoria(new Categorias(Constantes.CATEGORIA_BODEGA));
                            modeloBaterias.agregarBateria(bateriaTemporal, 0);//agrega al inicio de la tabla
                            bateria_seleccionada = null;
                        }
                    } catch (Exception ex) {
                        JOptionPane.showMessageDialog(Principal.getInstance(), ex.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
                    }
                }
            });
            cementerio_menuB.addActionListener(new ActionListener() {

                @Override
                public void actionPerformed(ActionEvent e) {
                    try {
                        if (bateria_seleccionada != null) {
                            bateria_seleccionada.getContenedor().setEstaMontado(false);
                            baterias_finales.remove(bateria_seleccionada);
                            int pos = indiceDe(bateria_seleccionada, baterias_iniciales);
                            if (pos >= 0) {
                                bateria_seleccionada.setIdCategoria(Constantes.CATEGORIA_CEMENTERIO);
                                baterias_iniciales.set(pos, bateria_seleccionada);
                            }
                            lienzo.repaint();
                            BateriasJpaController dao = new BateriasJpaController(null);
                            Baterias bateriaTemporal = dao.findBaterias(bateria_seleccionada.getIdBateria());
                            bateriaTemporal.setIdCategoria(new Categorias(Constantes.CATEGORIA_CEMENTERIO));
                            modeloBaterias.agregarBateria(bateriaTemporal, 0);//agrega al inicio de la tabla
                            bateria_seleccionada = null;
                        }
                    } catch (Exception ex) {
                        JOptionPane.showMessageDialog(Principal.getInstance(), ex.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
                    }
                }
            });
            reparacion_menuB.addActionListener(new ActionListener() {

                @Override
                public void actionPerformed(ActionEvent e) {
                    try {
                        if (bateria_seleccionada != null) {
                            bateria_seleccionada.getContenedor().setEstaMontado(false);
                            baterias_finales.remove(bateria_seleccionada);
                            int pos = indiceDe(bateria_seleccionada, baterias_iniciales);
                            if (pos >= 0) {
                                bateria_seleccionada.setIdCategoria(Constantes.CATEGORIA_REPARACION);
                                baterias_iniciales.set(pos, bateria_seleccionada);
                            }
                            lienzo.repaint();
                            BateriasJpaController dao = new BateriasJpaController(null);
                            Baterias bateriaTemporal = dao.findBaterias(bateria_seleccionada.getIdBateria());
                            bateriaTemporal.setIdCategoria(new Categorias(Constantes.CATEGORIA_REPARACION));
                            modeloBaterias.agregarBateria(bateriaTemporal, 0);//agrega al inicio de la tabla
                            bateria_seleccionada = null;
                        }
                    } catch (Exception ex) {
                        JOptionPane.showMessageDialog(Principal.getInstance(), ex.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
                    }
                }
            });
            
            
            Window window = SwingUtilities.windowForComponent(Principal.getInstance());
            toolTip = new JWindow(window);
            label = new JLabel() {

                @Override
                public void paint(Graphics g) {
                    int width = getWidth();
                    int height = getHeight();
                    GradientPaint paint = new GradientPaint(width / 2, 0, Color.white, width / 2, height, new Color(190, 190, 190), true);
                    Graphics2D g2d = (Graphics2D) g;
                    g2d.setColor(Color.black);
                    g2d.setStroke(new BasicStroke());
                    g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER));
                    g2d.setFont(new Font("Tahoma", Font.PLAIN, 12));
                    // save the old paint
                    Paint oldPaint = g2d.getPaint();
                    // set the paint to use for this operation
                    g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
                    g2d.setPaint(paint);
                    // fill the background using the paint
                    g2d.fillRect(0, 0, width, height);
                    g2d.setColor(new Color(102, 102, 102));
                    g2d.drawRect(0, 0, width - 1, height - 1);
                    g2d.setPaint(oldPaint);
                    super.paint(g);
                }
            };
            label.setHorizontalAlignment(JLabel.CENTER);
            label.setOpaque(false);
            label.setBorder(javax.swing.BorderFactory.createEmptyBorder(10, 10, 10, 10));
            label.setForeground(new java.awt.Color(40, 40, 40));
            toolTip.add(label, BorderLayout.CENTER);
            
            setOpaque(true);

            timer = new Timer(200, new ActionListener() {

                @Override
                public void actionPerformed(ActionEvent e) {
                    contador++;
                    if (contador == 10 && entro && !isToolTipShowing()) {
//                        Point p = new Point(llanta_seleccionada.getEje().getX(), llanta_seleccionada.getEje().getY());
                        showToolTip(descripcion, point_screen);
                    }
                }
            });
            timer.start();


        } catch (Exception ex) {
            JOptionPane.showMessageDialog(Principal.getInstance(), ex.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
        }
    }

    public boolean isToolTipShowing() {
        return toolTip.isShowing();
    }

    private void inicializarImagenes() {
        if (vehiculo != null) {
            if (vehiculo.getIdTipo().getId() == Constantes.REMOLQUE) {
                imagen = (new javax.swing.ImageIcon(getClass().getResource("/com/camachosanchez/recursos/cabezal-a.png"))).getImage();
                tipo_vehiculo = Constantes.REMOLQUE;
            } else if (vehiculo.getIdTipo().getId() == Constantes.SEMIREMOLQUE) {
                imagen = (new javax.swing.ImageIcon(getClass().getResource("/com/camachosanchez/recursos/chasis-a.png"))).getImage();
                tipo_vehiculo = Constantes.SEMIREMOLQUE;
            } else if (vehiculo.getIdTipo().getId() == Constantes.FURGON) {
                imagen = (new javax.swing.ImageIcon(getClass().getResource("/com/camachosanchez/recursos/bus-a.png"))).getImage();
                tipo_vehiculo = Constantes.FURGON;
            }
        }
    }

    public void generarEsquemaMontaje() {
        int max_num_llantas_x_eje = 0, num_ejes, pos = 0;
        int esquema[];
        ejes = new ArrayList<Eje>();
        List<Ejes> sistema_ejes = vehiculo.getIdTipoEje().getEjesList();
        Collections.sort(sistema_ejes);
        num_ejes = sistema_ejes.size();
        w_img = imagen.getWidth(this);
        h_img = imagen.getHeight(this);
        centro = new Point(lienzo.getWidth(), lienzo.getHeight());
        img_x = (centro.x - w_img) - 20;//-/2
        img_y = (centro.y - h_img) / 2;
        esquema = new int[sistema_ejes.size()];
        //ENCONTRAMOS EL MÁXIMO NÚMERO DE NEUMÁTICOS POR EJE
        int cantidadNeumaticos = 0;
        for (Ejes e : sistema_ejes) {
            int num_neumaticos = e.getNumNeumaticos();
            cantidadNeumaticos += num_neumaticos;
            if (num_neumaticos > max_num_llantas_x_eje) {
                max_num_llantas_x_eje = num_neumaticos;
            }
            //ESTABLECEMOS EL NÚMERO DE VEHÍCULOS POR EJE
            esquema[pos++] = num_neumaticos;
        }
        max_num_llantas_x_eje /= 2;
        int posicion = cantidadNeumaticos;//para que empiece desde 1
        if (tipo_vehiculo == Constantes.SEMIREMOLQUE) {
            int ancho_total = 350;
            int alto_total = 90;
            int ancho_llanta;
            if (num_ejes < 4) {
                ancho_llanta = 100;
            } else {
                ancho_llanta = ancho_total / num_ejes;
            }
            if (max_num_llantas_x_eje == 1) {
                alto_total = 50;
            }
            int alto_llanta = alto_total / max_num_llantas_x_eje;
            int xi = img_x + 295;
            int yi = img_y;

            for (int i = 0; i < sistema_ejes.size(); i++) {
                //NÚMERO DE LLANTAS A CADA LADO DEL EJE
                int limite = esquema[i] / 2;
//                //ARRIBA
                int pos_x = xi + ancho_total - (i + 1) * ancho_llanta;
                for (int j = 0; j < limite; j++) {
                    int pos_y = yi + alto_llanta * j;
                    Eje eje = new Eje(pos_x, pos_y, ancho_llanta, alto_llanta, posicion--, false, false);
                    ejes.add(eje);
                }
                //ABAJO
//                int k = -1;
                for (int j = 0, k = 1; j < limite; j++, k++) {
                    int pos_y = yi + imagen.getHeight(this) - alto_llanta * (j + 1);
                    Eje eje = new Eje(pos_x, pos_y, ancho_llanta, alto_llanta, posicion - (limite - k), false, false);
//                    k++;
                    ejes.add(eje);
                }
//                k++;
                posicion -= limite;
            }
            Eje ejeR1 = new Eje(78 - (ancho_llanta / 2), lienzo.getHeight() - 80 - (alto_llanta / 2), ancho_llanta, alto_llanta, 0, false, false);
            Eje ejeR2 = new Eje(193 - (ancho_llanta / 2), lienzo.getHeight() - 80 - (alto_llanta / 2), ancho_llanta, alto_llanta, -1, false, false);
            ejes.add(ejeR1);
            ejes.add(ejeR2);
        } else if (tipo_vehiculo == Constantes.REMOLQUE) {
            int ancho_total = 240;
            int alto_total = 80;
            int ancho_llanta;
            if (num_ejes < 4) {
                ancho_llanta = 80;
            } else {
                ancho_llanta = ancho_total / (num_ejes);
            }
            int xi = img_x + 408;
            int yi = img_y;
            int alto_llanta = 0;
            if (max_num_llantas_x_eje > 0) {
                alto_llanta = alto_total / max_num_llantas_x_eje;
            }
            for (int i = 0; i < sistema_ejes.size() - 1; i++) {
                int limite = esquema[i] / 2;
                //Arriba
                int pos_x = xi + ancho_total - (i + 1) * ancho_llanta;
                for (int j = 0; j < limite; j++) {
                    int pos_y = yi + alto_llanta * j;
                    Eje eje = new Eje(pos_x, pos_y, ancho_llanta, alto_llanta, posicion--, false, false);
                    ejes.add(eje);
                }
                //Abajo
                for (int j = 0, k = 1; j < limite; j++, k++) {
                    int pos_y = yi + imagen.getHeight(this) - alto_llanta * (j + 1);
                    Eje eje = new Eje(pos_x, pos_y, ancho_llanta, alto_llanta, posicion - (limite - k), false, false);
                    ejes.add(eje);
                }
                posicion -= limite;
            }
            xi = img_x + 45;
            int limite = esquema[sistema_ejes.size() - 1] / 2;
            //Delanteras derecha
            for (int j = 0; j < limite; j++) {
                int pos_y = yi + alto_llanta * j;
                Eje eje = new Eje(xi, pos_y, ancho_llanta, alto_llanta, posicion--, false, false);
                ejes.add(eje);
            }
            //Delanteras izquierda
            for (int j = 0, k = 1; j < limite; j++, k++) {
                int pos_y = yi + imagen.getHeight(this) - alto_llanta * (j + 1);
                Eje eje = new Eje(xi, pos_y, ancho_llanta, alto_llanta, posicion - (limite - k), false, false);
                ejes.add(eje);
            }
            posicion -= limite;
            Eje ejeR1 = new Eje(78 - (ancho_llanta / 2), lienzo.getHeight() - 80 - (alto_llanta / 2), ancho_llanta, alto_llanta, 0, false, false);
            Eje ejeR2 = new Eje(193 - (ancho_llanta / 2), lienzo.getHeight() - 80 - (alto_llanta / 2), ancho_llanta, alto_llanta, -1, false, false);
            ejes.add(ejeR1);
            ejes.add(ejeR2);
        } else if (tipo_vehiculo == Constantes.FURGON) {
            int alto_total = 80;
            if (max_num_llantas_x_eje < 2) {
                alto_total = 40;
            }
            int ancho_llanta = 100;
            int alto_llanta = alto_total / max_num_llantas_x_eje;
            int valores[] = null;
            int yi = img_y;
            int anchoLienzo = lienzo.getWidth();
            switch (num_ejes) {
                case 2:
                    valores = new int[]{anchoLienzo - 250, anchoLienzo - 620};
                    break;
                case 3:
                    valores = new int[]{anchoLienzo - 230, anchoLienzo - 330, anchoLienzo - 620};
                    break;
                case 4:
                    ancho_llanta = 80;
                    valores = new int[]{anchoLienzo - 210, anchoLienzo - 290, anchoLienzo - 530, anchoLienzo - 610};
                    break;
            }
            for (int i = 0; i < sistema_ejes.size(); i++) {
                int limite = esquema[i] / 2;
                //Arriba
                int pos_x = valores[i];
                for (int j = 0; j < limite; j++) {
                    int pos_y = yi + alto_llanta * j + 20;
                    Eje eje = new Eje(pos_x, pos_y, ancho_llanta, alto_llanta, posicion--, false, false);
                    ejes.add(eje);
                }
                //Abajo
                for (int j = 0, k = 1; j < limite; j++, k++) {
                    int pos_y = yi + imagen.getHeight(this) - alto_llanta * (j + 1) - 20;
                    Eje eje = new Eje(pos_x, pos_y, ancho_llanta, alto_llanta, posicion - (limite - k), false, false);
                    ejes.add(eje);
                }
                posicion -= limite;
            }
            Eje ejeR1 = new Eje(78 - (ancho_llanta / 2), lienzo.getHeight() - 80 - (alto_llanta / 2), ancho_llanta, alto_llanta, 0, false, false);
            Eje ejeR2 = new Eje(193 - (ancho_llanta / 2), lienzo.getHeight() - 80 - (alto_llanta / 2), ancho_llanta, alto_llanta, -1, false, false);
            ejes.add(ejeR1);
            ejes.add(ejeR2);
        }
        
        contBaterias = new ArrayList<ContenedorBateria>();
        int xb = 0;
        for(int i = 0; i < nroBaterias ; i++){
            ContenedorBateria cont = new ContenedorBateria(280 + xb, lienzo.getHeight() - 80 - (altoB / 2), anchoB, altoB, i + 1, false);
            contBaterias.add(cont);
            xb += anchoB + 10;
        }
        
        if (!ejes.isEmpty()) {
            ControlCambioNeumaticoJdbcControler daoJdbc = new ControlCambioNeumaticoJdbcControler();
            ControlCambioNeumatico control = daoJdbc.findUltimoControlCambio(vehiculo.getId());
            if(control != null){
                List<DetalleControlCambioNeumatico> detalles = control.getDetalleControlCambioNeumaticoList();
                Collections.sort(detalles);
                if(!detalles.isEmpty()){
                    this.comboPilotos.setSelectedItem(control.getIdPiloto());
                    this.dateFechaMontaje.setMinSelectableDate(control.getFecha());
                }
                llantas_iniciales = new ArrayList<Llanta>();
                llantas_finales = new ArrayList<Llanta>();
                for (DetalleControlCambioNeumatico detalle : detalles) {
                    if (detalle.getTipo() == Constantes.MONTAJE || detalle.getTipo() == Constantes.SIN_MOVIMIENTO) {
                        int ubicacion = detalle.getPosicion();
                        for (Eje eje : ejes) {
                            if (eje.getPosicion() == ubicacion) {
                                Llanta llanta = new Llanta(eje, detalle.getIdNeumatico().getId(), lienzo.getWidth(), lienzo.getHeight());
                                llanta.setOrigen(Constantes.FROM_DB);
                                llanta.setIdCategoria(detalle.getIdNeumatico().getIdCategoria().getId());
                                llanta.setCodigo(detalle.getIdNeumatico().getCodigo());
                                llantas_iniciales.add(llanta);
                                llantas_finales.add((Llanta) llanta.clone());
                                eje.setEstaMontado(true);
                                String strUbicacion = "" + ubicacion;
                                if (ubicacion <= 0) {
                                    strUbicacion = "R";
                                }
                                tablaInformacion.add(strUbicacion + "¬" + detalle.getIdNeumatico().getCodigo() + "¬" + detalle.getIdNeumatico().getIdModelo().getMedida());
                                break;
                            }
                        }
                    }
                }

                List<DetalleControlCambioBateria> detallesB = control.getDetalleControlCambioBateriaList();
                Collections.sort(detallesB);
                baterias_iniciales = new ArrayList<Bateria>();
                baterias_finales = new ArrayList<Bateria>();
                for (DetalleControlCambioBateria item : detallesB) {
                    if (item.getTipo() == Constantes.MONTAJE || item.getTipo() == Constantes.SIN_MOVIMIENTO) {
                        int ubicacion = item.getPosicion();
                        for (ContenedorBateria cont : contBaterias) {
                            if (cont.getPosicion() == ubicacion) {
                                Bateria bateria = new Bateria(cont, item.getIdBateria().getId(), lienzo.getWidth(), lienzo.getHeight());
                                bateria.setOrigen(Constantes.FROM_DB);
                                bateria.setIdCategoria(item.getIdBateria().getIdCategoria().getId());
                                bateria.setCodigo(item.getIdBateria().getCodigo());
                                baterias_iniciales.add(bateria);
                                baterias_finales.add((Bateria) bateria.clone());
                                cont.setEstaMontado(true);
                                String strUbicacion = "" + ubicacion;
                                if (ubicacion <= 0) {
                                    strUbicacion = "R";
                                }
                                tablaInformacionBaterias.add(strUbicacion + "¬" + item.getIdBateria().getCodigo() + "¬" + item.getIdBateria().getIdMarca().getNombre());
                                break;
                            }
                        }
                    }
                }
            }
        }
    }

    private int indiceDe(Llanta llanta, List<Llanta> llantas) {
        int pos = -1;
        int tam = llantas.size();
        for (int i = 0; i < tam; i++) {
            if (llantas.get(i).getIdNeumatico() == llanta.getIdNeumatico()) {
                pos = i;
                break;
            }
        }
        return pos;
    }
    
    private int indiceDe(Bateria bateria, List<Bateria> baterias) {
        int pos = -1;
        int tam = baterias.size();
        for (int i = 0; i < tam; i++) {
            if (baterias.get(i).getIdBateria() == bateria.getIdBateria()) {
                pos = i;
                break;
            }
        }
        return pos;
    }

    private void guardar() {
        EntityManager em = null;
        try {
            em = emf.createEntityManager();
            EntityTransaction tx = em.getTransaction();
            tx.begin();
            //------------------------------------------
            Usuarios user = Constantes.currentUser;

            ControlCambioNeumatico control_cambio = new ControlCambioNeumatico();
            if (comboTalleres.getSelectedItem() != null) {
                control_cambio.setIdTaller((Talleres) comboTalleres.getSelectedItem());
            } else {
                JOptionPane.showMessageDialog(this, "Se debe asignar un taller en la realización de un montaje/desmontaje.\nSi no existe uno, agréguelo desde el menú de Logística.", "Datos incorrectos", JOptionPane.WARNING_MESSAGE);
                comboTalleres.requestFocusInWindow();
                return;
            }
            if (comboPilotos.getSelectedItem() != null) {
                control_cambio.setIdPiloto((Pilotos) comboPilotos.getSelectedItem());
            } else {
                JOptionPane.showMessageDialog(this, "Se debe asignar un piloto en la realización de un montaje/desmontaje.\nSi no existe uno, agréguelo desde el menú de Logística.", "Datos incorrectos", JOptionPane.WARNING_MESSAGE);
                comboPilotos.requestFocusInWindow();
                return;
            }

            control_cambio.setFecha(dateFechaMontaje.getDate());
            control_cambio.setComentario(txpComentarios.getText());
            double kilometraje;
            try {
                kilometraje = Double.parseDouble(txtKilometraje.getText());
                control_cambio.setKilometraie(kilometraje);
            } catch (NumberFormatException e) {
                JOptionPane.showMessageDialog(this, "El valor ingresado para el kilometraje debe ser un número.", "Datos incorrectos", JOptionPane.WARNING_MESSAGE);
                txtKilometraje.requestFocusInWindow();
                return;
            }
            control_cambio.setIdUsuario(user);
            control_cambio.setFechaInsercionActualizacion(new Date());

            Boolean kmNuevo = false;
            List<DetalleControlCambioNeumatico> detalleControlCambio = new ArrayList<DetalleControlCambioNeumatico>();
            List<DetalleControlCambioBateria> detalleControlCambioBaterias = new ArrayList<DetalleControlCambioBateria>();
            
            Vehiculos vehiculoTmp = (Vehiculos) em.getReference(Vehiculos.class, vehiculo.getId());

            //2. REGISTRAR LOS DESMONTAJES DE NEUMÁTICOS
            for (Llanta llanta : llantas_iniciales) {
                DetalleControlCambioNeumatico dc = new DetalleControlCambioNeumatico();
                dc.setIdControlCambioNeumatico(control_cambio);
                if (esNeumaticoDesmontado(llanta, llantas_finales)) {
                    dc.setTipo(-1);//Desmontaje
                    dc.setFechaInsercionActualizacion(new Date());
                    Neumaticos tire = (Neumaticos) em.getReference(Neumaticos.class, llanta.getIdNeumatico());
                    Categorias categoria = new Categorias(llanta.getIdCategoria());
                    tire.setIdCategoria(categoria);
                    tire.setIdUsuario(user);
                    tire.setFechaInsercionActualizacion(new Date());
                    tire.setInfMontaje("");//no hay información de montaje porque se encuantra desmontado

                    if (!esCambioPosicion(llanta, llantas_finales)) {
                        //si no se está realizando solo un cambio de posición, desmontado y vuelto a montar
                        //O ES DESMONTADO DE LAS LLANTAS_INICIALES
                        int kmTotal = (tire.getKmTotal() == null) ? 0 : tire.getKmTotal();
                        int kmMontaje = (tire.getKmAlMontaje() == null) ? 0 : tire.getKmAlMontaje();
                        if (kmMontaje == 0) {//si es el primer montaje
                            tire.setKmTotal(kmTotal);
                        } else {
                            if (kmMontaje >= kilometraje && kmNuevo == false) {
                                DialogoKilometrajeNuevo guiKmNuevo = new DialogoKilometrajeNuevo(Principal.getInstance(), true);
                                guiKmNuevo.setVisible(true);
                                if (guiKmNuevo.getGuardar()) {
                                    kmNuevo = true;
                                    tire.setKmTotal(kmTotal + (int) kilometraje);
                                } else {
                                    kmNuevo = false;
                                    txtKilometraje.setText(kmMontaje + "");
                                    txtKilometraje.requestFocusInWindow();
                                    txtKilometraje.selectAll();
                                    return;
                                }
                                guiKmNuevo.dispose();
//                                JOptionPane.showMessageDialog(this, "El kilometraje de este vehículo, debe ser mayor que el kilometraje del movimiento anterior de este mismo vehículo.", "Datos incorrectos", JOptionPane.WARNING_MESSAGE);
                            } else if (kmMontaje >= kilometraje && kmNuevo) {
                                tire.setKmTotal(kmTotal + (int) kilometraje);
                            } else {
                                tire.setKmTotal(kmTotal + ((int) kilometraje - kmMontaje));
                            }

                        }
                        tire.setKmAlMontaje(0);//si se está desmontando, km al montaje se vuelve cero
                    }

                    dc.setIdNeumatico(tire);
                    dc.setPosicion(llanta.getEje().getPosicion());
                    detalleControlCambio.add(dc);
                }
            }
            //----------------------------

            Categorias categoriaMontado = new Categorias(Constantes.CATEGORIA_MONTADO);
            //3. REGISTRAR LOS MONTAJES O LOS MOVIMIENTOS NEUTROS DE LOS NEUMÁTICOS
            for (Llanta llanta : llantas_finales) {
                DetalleControlCambioNeumatico dc = new DetalleControlCambioNeumatico();
                dc.setIdControlCambioNeumatico(control_cambio);
                dc.setId(0);
                if (esNeumaticoMontado(llanta, llantas_iniciales)) {
                    dc.setTipo(1);//Montaje
                } else {
                    dc.setTipo(0);//Neutro
                }
                dc.setFechaInsercionActualizacion(new Date());
                Neumaticos tire = (Neumaticos) em.getReference(Neumaticos.class, llanta.getIdNeumatico());
                tire.setIdCategoria(categoriaMontado);
                tire.setIdUsuario(user);
                tire.setFechaInsercionActualizacion(new Date());
                String posicion = (llanta.getEje().getPosicion() <= 0) ? "R" : llanta.getEje().getPosicion() + "";
                tire.setInfMontaje((vehiculo.getCodBarras() != null ? vehiculo.getCodBarras() : "") + " : " + vehiculo.getPlaca() + " : " + posicion);
                //kilometraje del neumático
                if (esCambioPosicion(llanta, llantas_iniciales) || !esNeumaticoMontado(llanta, llantas_iniciales)) {
                    //solo para los que cambian de posición, desmontado y vuelto a montar, o es neutro
                    //los recién montados aún no hay un cálculo del km recorrido
                    int kmTotal = (tire.getKmTotal() == null) ? 0 : tire.getKmTotal();
                    int kmMontaje = (tire.getKmAlMontaje() == null) ? 0 : tire.getKmAlMontaje();
                    if (kmMontaje == 0) {//si es el primer montaje
                        tire.setKmTotal(kmTotal);
                    } else {
                        if (kmMontaje >= kilometraje && kmNuevo == false) {
                            DialogoKilometrajeNuevo guiKmNuevo = new DialogoKilometrajeNuevo(Principal.getInstance(), true);
                            guiKmNuevo.setVisible(true);
                            if (guiKmNuevo.getGuardar()) {
                                kmNuevo = true;
                                tire.setKmTotal(kmTotal + (int) kilometraje);
                            } else {
                                kmNuevo = false;
                                txtKilometraje.setText(kmMontaje + "");
                                txtKilometraje.requestFocusInWindow();
                                txtKilometraje.selectAll();
                                return;
                            }
                            guiKmNuevo.dispose();
                        } else if (kmMontaje >= kilometraje && kmNuevo) {
                            tire.setKmTotal(kmTotal + (int) kilometraje);
                        } else {
                            tire.setKmTotal(kmTotal + ((int) kilometraje - kmMontaje));
                        }
                    }
                }
                tire.setKmAlMontaje((int) kilometraje);
                tire.setFechaMontaje(control_cambio.getFecha());

                dc.setIdNeumatico(tire);
                dc.setPosicion(llanta.getEje().getPosicion());
                detalleControlCambio.add(dc);
            }
            
            //2. REGISTRAR LOS DESMONTAJES DE BATERÍAS
            for (Bateria bateriaIni : baterias_iniciales) {
                DetalleControlCambioBateria dc = new DetalleControlCambioBateria();
                dc.setIdControlCambioNeumatico(control_cambio);
                if (esBateriaDesmontada(bateriaIni, baterias_finales)) {
                    dc.setTipo(Short.valueOf(-1 + ""));//Desmontaje
                    Baterias b = (Baterias) em.getReference(Baterias.class, bateriaIni.getIdBateria());
                    Categorias categoria = new Categorias(bateriaIni.getIdCategoria());
                    b.setIdCategoria(categoria);
                    b.setIdUsuario(user);
                    b.setFechaInsercionActualizacion(new Date());
                    b.setInfMontaje("");//no hay información de montaje porque se encuantra desmontado
                    b.setFechaMontaje(null);
                    dc.setIdBateria(b);
                    int pos = bateriaIni.getContenedor().getPosicion();
                    dc.setPosicion(Short.valueOf(pos + ""));
                    detalleControlCambioBaterias.add(dc);
                }
            }
            //----------------------------

            //3. REGISTRAR LOS MONTAJES O LOS MOVIMIENTOS NEUTROS DE LAS BATERÍAS
            int posMaximaB = 0;
            for (Bateria bateriaFin : baterias_finales) {
                DetalleControlCambioBateria dc = new DetalleControlCambioBateria();
                dc.setIdControlCambioNeumatico(control_cambio);
                dc.setId(0);
                if (esBateriaDesmontada(bateriaFin, baterias_iniciales)) {
                    dc.setTipo(Short.valueOf(1 + ""));//Montaje
                } else {
                    dc.setTipo(Short.valueOf(0 + ""));//Neutro
                }
                Baterias b = (Baterias) em.getReference(Baterias.class, bateriaFin.getIdBateria());
                b.setIdCategoria(categoriaMontado);
                b.setIdUsuario(user);
                b.setFechaInsercionActualizacion(new Date());
                String posicion = bateriaFin.getContenedor().getPosicion() + "";
                b.setInfMontaje((vehiculo.getCodBarras() != null ? vehiculo.getCodBarras() : "") + " : " + vehiculo.getPlaca() + " : " + posicion);
                b.setFechaMontaje(control_cambio.getFecha());

                dc.setIdBateria(b);
                int pos = bateriaFin.getContenedor().getPosicion();
                dc.setPosicion(Short.valueOf(pos + ""));
                detalleControlCambioBaterias.add(dc);
                if(pos > posMaximaB){
                    posMaximaB = pos;
                }
            }
            vehiculoTmp.setNroMaxBaterias(Short.valueOf(posMaximaB + ""));
            
            //---------------------------------------------------
            control_cambio.setIdUsuario(user);
            if (kmNuevo) {
                vehiculoTmp.setKmActual(vehiculo.getKmActual() + (int) kilometraje);
            } else {
                vehiculoTmp.setKmActual((int) kilometraje);
            }
            control_cambio.setIdVehiculo(vehiculoTmp);
            control_cambio.setDetalleControlCambioNeumaticoList(detalleControlCambio);
            control_cambio.setDetalleControlCambioBateriaList(detalleControlCambioBaterias);
            em.persist(control_cambio);

            for (Llanta llanta : llantas_observadas) {
                Egresos e = llanta.getEgreso();
                e.setFecha(new Date());
                e.setIdVehiculos(vehiculo);
                e.setIdPilotos((Pilotos) comboPilotos.getSelectedItem());
                e.setConcepto("Pago por reparación de emergencia del neumático " + llanta.getCodigo());
                e.setTipo(Constantes.TIPO_LLANTAS);
                e.setAnulado(false);
                e.setIdUsuarios(Constantes.currentUser);
                em.persist(e);
            }

            tx.commit();
            JOptionPane.showMessageDialog(this, "El registro ha sido guardado correctamente.", "Operación finalizada", JOptionPane.INFORMATION_MESSAGE);
            this.setClosed(true);
        } catch (Exception e) {
            if (em.getTransaction().isActive()) {
                em.getTransaction().rollback();
            }
            JOptionPane.showMessageDialog(Principal.getInstance(), e.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    private boolean esNeumaticoMontado(Llanta llanta, List<Llanta> llantas) {
        for (Llanta aux : llantas) {
            if (aux.getEje().getPosicion() == llanta.getEje().getPosicion() && aux.getIdNeumatico() == llanta.getIdNeumatico()) {
                return false;
            }
        }
        return true;
    }

    private boolean esNeumaticoDesmontado(Llanta llanta, List<Llanta> llantas) {
        for (Llanta aux : llantas) {
            if (aux.getEje().getPosicion() == llanta.getEje().getPosicion() && aux.getIdNeumatico() == llanta.getIdNeumatico()) {
                return false;
            }
        }
        return true;
    }
    
    private boolean esBateriaDesmontada(Bateria bateria, List<Bateria> baterias) {
        for (Bateria aux : baterias) {
            if (aux.getContenedor().getPosicion() == bateria.getContenedor().getPosicion() && aux.getIdBateria() == bateria.getIdBateria()) {
                return false;
            }
        }
        return true;
    }

    private boolean esCambioPosicion(Llanta llanta, List<Llanta> llantas) {
        for (Llanta aux : llantas) {
            if (aux.getIdNeumatico() == llanta.getIdNeumatico() && llanta.getEje().getPosicion() != aux.getEje().getPosicion()) {
                return true;
            }
        }
        return false;
    }

    public void agregarDescripcionNeumaticos() {
        String[] columnNames = {"POSICIÓN", "CÓDIGO", "MEDIDA"};
        String[] columnNamesB = {"POSICIÓN", "CÓDIGO", "MARCA"};
        StringBuilder sb = new StringBuilder();
        sb.append("<html><body><center>");
        sb.append("<table  width='100%'>");
        sb.append("<tr><td colspan='3' align='center' bgcolor='#8CB1DA'><b>HOJA DE ENTRADA A MONTAJE</b></td></tr>");
        sb.append("<tr><td colspan='3' align='center' bgcolor='#8CB1DA'><b>NEUMÁTICOS</b></td></tr>");
        sb.append("<tr>");
        for (String columnName : columnNames) {
            sb.append("<td align='center' bgcolor='#C4D9EC'>");
            sb.append(columnName);
            sb.append("</td>");
        }
        sb.append("</tr>");
        String codigoNeumaticoSeleccionado = "";
        if (idNeumaticoResaltado > 0) {
            NeumaticosJdbcControler nc = new NeumaticosJdbcControler();
            Neumaticos neumaticoSeleccionado = nc.findNeumatico(idNeumaticoResaltado);
            if (neumaticoSeleccionado != null) {
                codigoNeumaticoSeleccionado = neumaticoSeleccionado.getCodigo();
            }
        }
        for (String string : tablaInformacion) {
            String[] valores = string.split("¬");
            if (valores.length == 3) {
                if (valores[1].compareTo(codigoNeumaticoSeleccionado) == 0) {
                    sb.append("<tr bgcolor='#FCDD82'>");
                } else {
                    sb.append("<tr bgcolor='#EAF1F6'>");
                }
                sb.append("<td align='center'>");
                sb.append(valores[0]);
                sb.append("</td>");
                sb.append("<td align='center'>");
                sb.append(valores[1]);
                sb.append("</td>");
                sb.append("<td align='center'>");
                sb.append(valores[2]);
                sb.append("</td>");
                sb.append("</tr>");
            }
        }
        sb.append("<tr><td colspan='3' align='center' bgcolor='#8CB1DA'><b>BATERÍAS</b></td></tr>");
        sb.append("<tr>");
        for (String columnName : columnNamesB) {
            sb.append("<td align='center' bgcolor='#C4D9EC'>");
            sb.append(columnName);
            sb.append("</td>");
        }
        sb.append("</tr>");
        String codigoBateriaSeleccionada = "";
        if (idBateriaResaltada > 0) {
            BateriasJpaController nc = new BateriasJpaController(null);
            Baterias bateriaSeleccionada = nc.findBaterias(idBateriaResaltada);
            if (bateriaSeleccionada != null) {
                codigoBateriaSeleccionada = bateriaSeleccionada.getCodigo();
            }
        }
        for (String string : tablaInformacionBaterias) {
            String[] valores = string.split("¬");
            if (valores.length == 3) {
                if (valores[1].compareTo(codigoBateriaSeleccionada) == 0) {
                    sb.append("<tr bgcolor='#FCDD82'>");
                } else {
                    sb.append("<tr bgcolor='#EAF1F6'>");
                }
                sb.append("<td align='center'>");
                sb.append(valores[0]);
                sb.append("</td>");
                sb.append("<td align='center'>");
                sb.append(valores[1]);
                sb.append("</td>");
                sb.append("<td align='center'>");
                sb.append(valores[2]);
                sb.append("</td>");
                sb.append("</tr>");
            }
        }
        sb.append("</table>");
        sb.append("</center></body>");
        sb.append("</html>");
        html = new JEditorPane(new HTMLEditorKit().getContentType(), sb.toString());
        Font font = UIManager.getFont("Label.font");
        String bodyRule = "body { font-family: " + font.getFamily() + "; " + "font-size: " + 11 + "pt;}";
        ((HTMLDocument) html.getDocument()).getStyleSheet().addRule(bodyRule);
        html.setContentType("text/html");
        html.setEditable(false);
        html.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));
//        html.setBorder(BorderFactory.create);
        html.setSize(html.getPreferredSize());
        html.setOpaque(true);
//        html.setBackground(new Color(235, 234, 250));
        Dimension d = html.getPreferredSize();
        lienzo.setLayout(null);
        lienzo.add(html);
        html.setBounds(20, 20, (int) d.getWidth(), (int) d.getHeight());
        lienzo.updateUI();
    }

    class Lienzo extends JPanel implements MouseListener, MouseMotionListener {

        @Override
        protected void paintComponent(Graphics g) {
            int width = this.getWidth();
            int height = this.getHeight();
            Graphics2D g2 = (Graphics2D) g;
            g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
//            g2.setColor(new Color(224, 224, 208));
            g2.setColor(Color.white);
            g2.fillRect(0, 0, width, height);
            g2.setColor(new Color(240, 240, 240));
            for (int i = 0; i < width; i++) {
                int k = i * 10;
                g2.drawLine(k, 0, k, height);
            }
            for (int i = 0; i < height; i++) {
                int k = i * 10;
                g2.drawLine(0, k, width, k);
            }
            g2.setColor(Color.black);
            float dash[] = {4.0f};
            g2.setStroke(new BasicStroke(1.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10.0f, dash, 0.0f));
            g2.drawRect(10, 10, width - 20, height - 20);
            g2.setStroke(new BasicStroke());
            GraphicsUtil.graficarCruz(g2, 5, 5, 10);
            GraphicsUtil.graficarCruz(g2, width - 15, height - 15, 10);
            GraphicsUtil.graficarCruz(g2, 5, height - 15, 10);
            GraphicsUtil.graficarCruz(g2, width - 15, 5, 10);
            g2.setColor(new Color(51, 51, 51));
            g2.setFont(new Font("Arial", Font.PLAIN, 12));
            g2.drawImage(imagen, img_x, img_y, w_img, h_img, this);
            g2.setStroke(new BasicStroke(1.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10.0f, dash, 0.0f));
            g2.drawLine(img_x + (w_img / 2), img_y - 30, img_x + (w_img / 2), img_y + h_img + 30);
            g2.drawLine(img_x - 30, img_y + (h_img / 2), img_x + w_img, img_y + (h_img / 2));
            g2.setStroke(new BasicStroke());
            g2.setColor(Color.white);
            g2.fillRect(20, height - 120, 230, 100);
            g2.setFont(new Font("Arial", Font.PLAIN, 12));
            g2.setColor(Color.black);
            String cadenaR = "NEUMÁTICOS DE REPUESTO";
            FontMetrics fontMetrics = g2.getFontMetrics();
            int anchoLetras = fontMetrics.stringWidth(cadenaR);
            g2.drawLine(20, height - 40, 250, height - 40);
            g2.drawString(cadenaR, 135 - (anchoLetras / 2), height - 25);
            g2.drawRect(20, height - 120, 230, 100);
            String cadenaB = "BATERIAS";
            fontMetrics = g2.getFontMetrics();
            int anchoLetrasB = fontMetrics.stringWidth(cadenaB);
            int largoB = nroBaterias * (anchoB + 10) + 10;
            if(nroBaterias == 0){
                largoB = anchoLetrasB + 10;
            }
            g2.drawLine(270, height - 40, largoB + 270, height - 40);
            g2.drawString(cadenaB, largoB/2 + 270 - (anchoLetrasB / 2), height - 25);
            g2.drawRect(270, height - 120, largoB, 100);
            if (ejes != null) {
                for (Eje eje : ejes) {
                    eje.graficar(g2);
                }
            }
            if (llantas_finales != null) {
                for (Llanta llanta : llantas_finales) {
                    llanta.graficar(g2);
                }
            }
            if (llantas_observadas != null) {
                for (Llanta llanta : llantas_observadas) {
                    llanta.graficarAdvertencia(g2);
                }
            }
            if (contBaterias != null) {
                for (ContenedorBateria cont : contBaterias) {
                    cont.graficar(g2);
                }
            }
            if (baterias_finales != null) {
                for (Bateria b : baterias_finales) {
                    b.graficar(g2);
                }
            }
            g2.setColor(Color.black);
            g2.drawLine(posX, 0, posX, height);
            g2.drawLine(0, posY, width, posY);
            g2.setFont(new Font("Arial", Font.BOLD, 16));
            fontMetrics = g2.getFontMetrics();
            String descripcionUnidad = ("Unidad: [" + vehiculo.getIdTipo().getNombre() + " / " + vehiculo.getPlaca() + "] - Modelo de ejes: [" + vehiculo.getIdTipoEje().getNombre()).toUpperCase() + "]";
            int anchoDescripcion = fontMetrics.stringWidth(descripcionUnidad);
            g2.drawString(descripcionUnidad, width - anchoDescripcion - 20, 35);
            if(mostrarNeumaticosPos){
                Dimension d = html.getPreferredSize();
                lienzo.setLayout(null);
                lienzo.add(html);
                html.setBounds(20, 20, (int) d.getWidth(), (int) d.getHeight());
            } else {
                lienzo.remove(html);
            }
            lienzo.updateUI();
        }

        @Override
        public void mouseClicked(MouseEvent e) {
        }

        @Override
        public void mousePressed(MouseEvent e) {
            idNeumaticoResaltado = -5;
            this.requestFocus();
            for (Llanta llanta : llantas_finales) {
                if (llanta.estaDentro(e.getPoint())) {
                    draggedPoint = llanta.getIdNeumatico();
                    break;
                }
            }
            idBateriaResaltada = -5;
            for (Bateria b : baterias_finales) {
                if (b.estaDentro(e.getPoint())) {
                    draggedPointBateria = b.getIdBateria();
                    break;
                }
            }
        }

        @Override
        public void mouseReleased(MouseEvent e) {
            idNeumaticoResaltado = -5;
            idBateriaResaltada = -5;
            boolean found = false;
            if (!SwingUtilities.isRightMouseButton(e)) {
                if (arrastra) {
                    for (Eje eje : ejes) {
                        if (eje.estaDentro(e.getPoint()) && !eje.isEstaMontado()) {
                            eje.setEstaMontado(true);
                            llanta_arrastrada.setX(eje.getX());
                            llanta_arrastrada.setY(eje.getY());
                            llanta_arrastrada.setEje(eje);
                            eje_seleccionado.setEstaMontado(false);
                            found = true;
                            break;
                        }
                    }
                    if (!found && llanta_arrastrada != null) {
                        llanta_arrastrada.setX(eje_seleccionado.getX());
                        llanta_arrastrada.setY(eje_seleccionado.getY());
                    }
                    pintarPosiciones();
                }
                else if(arrastraBateria){
                    found = false;
                    for (ContenedorBateria cont : contBaterias) {
                        if (cont.estaDentro(e.getPoint()) && !cont.isEstaMontado()) {
                            cont.setEstaMontado(true);
                            bateria_arrastrada.setX(cont.getX());
                            bateria_arrastrada.setY(cont.getY());
                            bateria_arrastrada.setContenedor(cont);
                            contBateria_seleccionado.setEstaMontado(false);
                            found = true;
                            break;
                        }
                    }
                    if (!found && bateria_arrastrada != null) {
                        bateria_arrastrada.setX(contBateria_seleccionado.getX());
                        bateria_arrastrada.setY(contBateria_seleccionado.getY());
                    }
                    pintarPosiciones();
                }
            } else if (e.isPopupTrigger()) {
                hideToolTip();
                llanta_seleccionada = null;
                for (Llanta llanta : llantas_finales) {
                    if (llanta.estaDentro(e.getPoint())) {
                        llanta_seleccionada = llanta;
                        break;
                    }
                }
                if (llanta_seleccionada != null) {
                    popmenu.show(e.getComponent(), e.getX(), e.getY());
                }
                
                bateria_seleccionada = null;
                for (Bateria b : baterias_finales) {
                    if (b.estaDentro(e.getPoint())) {
                        bateria_seleccionada = b;
                        break;
                    }
                }
                if (bateria_seleccionada != null) {
                    popmenuBaterias.show(e.getComponent(), e.getX(), e.getY());
                }
            }
            draggedPoint = -1;
            draggedPointBateria = -1;
            llanta_arrastrada = null;
            eje_seleccionado = null;
            bateria_arrastrada = null;
            contBateria_seleccionado = null;
            arrastra = false;
            arrastraBateria = false;
            this.repaint();
        }

        @Override
        public void mouseEntered(MouseEvent e) {
        }

        @Override
        public void mouseExited(MouseEvent e) {
//            posX = -1;
//            posY = -1;
//            lienzo.repaint();
        }

        @Override
        public void mouseDragged(MouseEvent e) {
            idNeumaticoResaltado = -5;
            idBateriaResaltada = -5;
            entro = false;
            descripcion = "";
            point_screen = null;
            hideToolTip();
            if (e.getX() >= 0 && e.getY() >= 0) {
                if (!SwingUtilities.isRightMouseButton(e)) {
                    if (draggedPoint == -1 && draggedPointBateria == -1) {
                        return;
                    }else {
                        if(draggedPoint > -1){
                            if (llanta_arrastrada == null) {
                                xAnteriorRaton = (int) (e.getX());
                                yAnteriorRaton = (int) (e.getY());
                                for (Llanta llanta : llantas_finales) {
                                    if (llanta.estaDentro(e.getPoint())) {
                                        llanta_arrastrada = llanta;
                                        eje_seleccionado = llanta.getEje();
                                        break;
                                    }
                                }
                                if (llanta_arrastrada != null) {
                                    int indice = llantas_finales.indexOf(llanta_arrastrada);
                                    try {
                                        Collections.swap(llantas_finales, indice, llantas_finales.size() - 1);
                                    } catch (ArrayIndexOutOfBoundsException ex) {
                                        draggedPoint = -1;
                                        llanta_arrastrada = null;
                                        eje_seleccionado = null;
                                        JOptionPane.showMessageDialog(Principal.getInstance(), ex.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
                                    }
                                }

                            } else {
                                int xx, yy;
                                xx = llanta_arrastrada.getX() + (e.getX() - xAnteriorRaton);
                                yy = llanta_arrastrada.getY() + (e.getY() - yAnteriorRaton);
                                llanta_arrastrada.setX(xx);
                                llanta_arrastrada.setY(yy);
                                xAnteriorRaton = (int) e.getX();
                                yAnteriorRaton = (int) e.getY();
                                arrastra = true;
                                repaint();
                            }
                        } else if(draggedPointBateria > -1){
                            if (bateria_arrastrada == null) {
                                xAnteriorRaton = (int) (e.getX());
                                yAnteriorRaton = (int) (e.getY());
                                for (Bateria b : baterias_finales) {
                                    if (b.estaDentro(e.getPoint())) {
                                        bateria_arrastrada = b;
                                        contBateria_seleccionado = b.getContenedor();
                                        break;
                                    }
                                }
                                if (bateria_arrastrada != null) {
                                    int indice = baterias_finales.indexOf(bateria_arrastrada);
                                    try {
                                        Collections.swap(baterias_finales, indice, baterias_finales.size() - 1);
                                    } catch (ArrayIndexOutOfBoundsException ex) {
                                        draggedPointBateria = -1;
                                        bateria_arrastrada = null;
                                        contBateria_seleccionado = null;
                                        JOptionPane.showMessageDialog(Principal.getInstance(), ex.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
                                    }
                                }

                            } else {
                                int xx, yy;
                                xx = bateria_arrastrada.getX() + (e.getX() - xAnteriorRaton);
                                yy = bateria_arrastrada.getY() + (e.getY() - yAnteriorRaton);
                                bateria_arrastrada.setX(xx);
                                bateria_arrastrada.setY(yy);
                                xAnteriorRaton = (int) e.getX();
                                yAnteriorRaton = (int) e.getY();
                                arrastraBateria = true;
                                repaint();
                            }
                        }
                    }
                }
            }
        }

        @Override
        public void mouseMoved(MouseEvent e) {
            idNeumaticoResaltado = -5;
            idBateriaResaltada = -5;
            entro = false;
            contador = 0;
            for (Llanta llanta : llantas_finales) {
                if (llanta.estaDentro(e.getPoint())) {
                    entro = true;
                    point_screen = e.getLocationOnScreen();
                    descripcion = llanta.getDescripcion();
                    return;
                }
            }
            for (Bateria b : baterias_finales) {
                if (b.estaDentro(e.getPoint())) {
                    entro = true;
                    point_screen = e.getLocationOnScreen();
                    descripcion = b.getDescripcion();
                    return;
                }
            }
            hideToolTip();
//            posX = e.getX();
//            posY = e.getY();
//            lienzo.repaint();
        }
    }

    public void showToolTip(String descripcion, Point p) {
        try {
            label.setText(descripcion);
            toolTip.pack();
            int w = toolTip.getWidth();
            int h = toolTip.getHeight();
            int p_aux = p.y + h;
            int pivote_y = this.getLocationOnScreen().y + this.getHeight();
            if (p_aux > pivote_y) {
                p.y = p.y - h;
            }
            popmenu.setVisible(false);
            toolTip.setLocation(p);
            toolTip.setVisible(true);
        } catch (Exception ex) {
            JOptionPane.showMessageDialog(Principal.getInstance(), ex.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
        }
    }

    public void hideToolTip() {
        try {
            entro = false;
            descripcion = "";
            toolTip.dispose();
        } catch (Exception ex) {
            JOptionPane.showMessageDialog(Principal.getInstance(), ex.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
        }
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jToolBar1 = new javax.swing.JToolBar();
        jPanel5 = new javax.swing.JPanel();
        btnGuardar = new javax.swing.JButton();
        btnPosiciones = new javax.swing.JButton();
        btnNeumaticos = new javax.swing.JButton();
        jButton1 = new javax.swing.JButton();
        jPanel3 = new javax.swing.JPanel();
        jPanel2 = new javax.swing.JPanel();
        jTabbedPane1 = new javax.swing.JTabbedPane();
        jPanel4 = new javax.swing.JPanel();
        jScrollPane2 = new javax.swing.JScrollPane();
        txpComentarios = new javax.swing.JTextPane();
        jLabel6 = new javax.swing.JLabel();
        jPanel1 = new javax.swing.JPanel();
        jPanel6 = new javax.swing.JPanel();
        jLabel7 = new javax.swing.JLabel();
        jLabel2 = new javax.swing.JLabel();
        jLabel4 = new javax.swing.JLabel();
        jLabel5 = new javax.swing.JLabel();
        jPanel7 = new javax.swing.JPanel();
        dateFechaMontaje = new com.toedter.calendar.JDateChooser();
        txtKilometraje = new javax.swing.JTextField();
        panelPilotos = new javax.swing.JPanel();
        panelPatios = new javax.swing.JPanel();
        jTabbedPane2 = new javax.swing.JTabbedPane();
        jScrollPane1 = new javax.swing.JScrollPane();
        tablaLlantas = new javax.swing.JTable();
        jScrollPane3 = new javax.swing.JScrollPane();
        tablaBaterias = new javax.swing.JTable();
        cotenedor = new javax.swing.JPanel();

        setClosable(true);
        setIconifiable(true);
        setTitle(".:: Montaje y Desmontaje de Neumáticos ::.");

        jToolBar1.setBorder(javax.swing.BorderFactory.createEtchedBorder());
        jToolBar1.setFloatable(false);
        jToolBar1.setRollover(true);
        jToolBar1.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseEntered(java.awt.event.MouseEvent evt) {
                jToolBar1MouseEntered(evt);
            }
        });

        jPanel5.setBackground(new java.awt.Color(255, 255, 255));
        jPanel5.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.LEFT, 4, 4));

        btnGuardar.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/camachosanchez/recursos/24_save.png"))); // NOI18N
        btnGuardar.setToolTipText("Guardar");
        btnGuardar.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));
        btnGuardar.setFocusable(false);
        btnGuardar.setHorizontalTextPosition(javax.swing.SwingConstants.RIGHT);
        btnGuardar.setMaximumSize(new java.awt.Dimension(22, 22));
        btnGuardar.setMinimumSize(new java.awt.Dimension(22, 22));
        btnGuardar.setPreferredSize(new java.awt.Dimension(22, 22));
        btnGuardar.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        btnGuardar.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnGuardarActionPerformed(evt);
            }
        });
        jPanel5.add(btnGuardar);

        btnPosiciones.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/camachosanchez/recursos/24_posiciones.png"))); // NOI18N
        btnPosiciones.setToolTipText("Ver posiciones");
        btnPosiciones.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));
        btnPosiciones.setMaximumSize(new java.awt.Dimension(22, 22));
        btnPosiciones.setMinimumSize(new java.awt.Dimension(22, 22));
        btnPosiciones.setPreferredSize(new java.awt.Dimension(22, 22));
        btnPosiciones.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnPosicionesActionPerformed(evt);
            }
        });
        jPanel5.add(btnPosiciones);

        btnNeumaticos.setBackground(new java.awt.Color(242, 225, 175));
        btnNeumaticos.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/camachosanchez/recursos/16_detail.png"))); // NOI18N
        btnNeumaticos.setToolTipText("Mostrar/Ocultar Hoja de Entrada al Montaje");
        btnNeumaticos.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));
        btnNeumaticos.setContentAreaFilled(false);
        btnNeumaticos.setOpaque(true);
        btnNeumaticos.setPreferredSize(new java.awt.Dimension(22, 22));
        btnNeumaticos.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnNeumaticosActionPerformed(evt);
            }
        });
        jPanel5.add(btnNeumaticos);

        jButton1.setBackground(new java.awt.Color(242, 225, 175));
        jButton1.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/camachosanchez/recursos/eraser.png"))); // NOI18N
        jButton1.setText("Anular Egresos Registrados");
        jButton1.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));
        jButton1.setContentAreaFilled(false);
        jButton1.setOpaque(true);
        jButton1.setPreferredSize(new java.awt.Dimension(162, 22));
        jButton1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton1ActionPerformed(evt);
            }
        });
        jPanel5.add(jButton1);

        jToolBar1.add(jPanel5);

        getContentPane().add(jToolBar1, java.awt.BorderLayout.PAGE_START);

        jPanel3.setLayout(new java.awt.BorderLayout());

        jPanel2.setAutoscrolls(true);
        jPanel2.setMaximumSize(new java.awt.Dimension(200, 32767));
        jPanel2.setMinimumSize(new java.awt.Dimension(200, 0));
        jPanel2.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseEntered(java.awt.event.MouseEvent evt) {
                jPanel2MouseEntered(evt);
            }
        });

        jTabbedPane1.setBackground(new java.awt.Color(255, 255, 255));

        jScrollPane2.setViewportView(txpComentarios);

        jLabel6.setText("Comentarios:");

        jPanel1.setLayout(new java.awt.BorderLayout());

        jPanel6.setLayout(new java.awt.GridLayout(4, 1, 0, 4));

        jLabel7.setText("Fecha: ");
        jPanel6.add(jLabel7);

        jLabel2.setText("Kilometraje: ");
        jPanel6.add(jLabel2);

        jLabel4.setText("Piloto:");
        jPanel6.add(jLabel4);

        jLabel5.setText("Patio");
        jPanel6.add(jLabel5);

        jPanel1.add(jPanel6, java.awt.BorderLayout.LINE_START);

        jPanel7.setLayout(new java.awt.GridLayout(4, 1, 0, 4));

        dateFechaMontaje.setDateFormatString("dd/MM/yyyy");
        jPanel7.add(dateFechaMontaje);

        txtKilometraje.setText("0.0");
        jPanel7.add(txtKilometraje);

        panelPilotos.setBackground(new java.awt.Color(255, 255, 255));
        panelPilotos.setLayout(new java.awt.BorderLayout());
        jPanel7.add(panelPilotos);

        panelPatios.setBackground(new java.awt.Color(255, 255, 255));
        panelPatios.setLayout(new java.awt.BorderLayout());
        jPanel7.add(panelPatios);

        jPanel1.add(jPanel7, java.awt.BorderLayout.CENTER);

        javax.swing.GroupLayout jPanel4Layout = new javax.swing.GroupLayout(jPanel4);
        jPanel4.setLayout(jPanel4Layout);
        jPanel4Layout.setHorizontalGroup(
            jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel4Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(jScrollPane2, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 235, Short.MAX_VALUE)
                    .addComponent(jPanel1, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 235, Short.MAX_VALUE)
                    .addComponent(jLabel6, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 235, Short.MAX_VALUE))
                .addContainerGap())
        );
        jPanel4Layout.setVerticalGroup(
            jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel4Layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, 84, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jLabel6)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 64, Short.MAX_VALUE)
                .addContainerGap())
        );

        jTabbedPane1.addTab("Datos generales", jPanel4);

        jTabbedPane2.setFont(new java.awt.Font("Tahoma", 1, 11));

        jScrollPane1.setBorder(null);

        tablaLlantas.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {
                {null, null, null, null},
                {null, null, null, null},
                {null, null, null, null},
                {null, null, null, null}
            },
            new String [] {
                "Title 1", "Title 2", "Title 3", "Title 4"
            }
        ));
        tablaLlantas.setGridColor(new java.awt.Color(153, 153, 153));
        tablaLlantas.setRowHeight(22);
        tablaLlantas.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
        tablaLlantas.setShowHorizontalLines(false);
        jScrollPane1.setViewportView(tablaLlantas);

        jTabbedPane2.addTab("NEUMÁTICOS", jScrollPane1);

        jScrollPane3.setBorder(null);

        tablaBaterias.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {
                {null, null, null, null},
                {null, null, null, null},
                {null, null, null, null},
                {null, null, null, null}
            },
            new String [] {
                "Title 1", "Title 2", "Title 3", "Title 4"
            }
        ));
        tablaBaterias.setGridColor(new java.awt.Color(153, 153, 153));
        tablaBaterias.setRowHeight(22);
        tablaBaterias.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
        tablaBaterias.setShowHorizontalLines(false);
        jScrollPane3.setViewportView(tablaBaterias);

        jTabbedPane2.addTab("BATERÍAS", jScrollPane3);

        javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);
        jPanel2.setLayout(jPanel2Layout);
        jPanel2Layout.setHorizontalGroup(
            jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel2Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(jTabbedPane2, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 260, Short.MAX_VALUE)
                    .addComponent(jTabbedPane1, javax.swing.GroupLayout.Alignment.LEADING))
                .addContainerGap())
        );
        jPanel2Layout.setVerticalGroup(
            jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel2Layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jTabbedPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 363, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jTabbedPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 224, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap())
        );

        jPanel3.add(jPanel2, java.awt.BorderLayout.LINE_END);

        cotenedor.setBackground(new java.awt.Color(255, 255, 255));
        cotenedor.setMaximumSize(new java.awt.Dimension(900, 2147483647));
        cotenedor.setMinimumSize(new java.awt.Dimension(900, 600));
        cotenedor.setPreferredSize(new java.awt.Dimension(900, 600));
        cotenedor.setLayout(new java.awt.BorderLayout());
        jPanel3.add(cotenedor, java.awt.BorderLayout.CENTER);

        getContentPane().add(jPanel3, java.awt.BorderLayout.CENTER);

        pack();
    }// </editor-fold>//GEN-END:initComponents

private void btnGuardarActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnGuardarActionPerformed
// TODO add your handling code here:
    guardar();
}//GEN-LAST:event_btnGuardarActionPerformed

private void jToolBar1MouseEntered(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jToolBar1MouseEntered
// TODO add your handling code here:
    hideToolTip();
}//GEN-LAST:event_jToolBar1MouseEntered

private void jPanel2MouseEntered(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jPanel2MouseEntered
// TODO add your handling code here:
    hideToolTip();
}//GEN-LAST:event_jPanel2MouseEntered

    private void btnPosicionesActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnPosicionesActionPerformed
        // TODO add your handling code here:
        posiciones = !posiciones;
        this.pintarPosiciones();
        lienzo.repaint();
    }//GEN-LAST:event_btnPosicionesActionPerformed

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed
// TODO add your handling code here:
    llantas_observadas = new ArrayList<Llanta>();
    lienzo.repaint();
}//GEN-LAST:event_jButton1ActionPerformed

    private void btnNeumaticosActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnNeumaticosActionPerformed
        // TODO add your handling code here:
        mostrarNeumaticosPos = !mostrarNeumaticosPos;
        lienzo.repaint();
    }//GEN-LAST:event_btnNeumaticosActionPerformed

    public void pintarPosiciones() {
        if (llantas_finales != null) {
            for (Llanta llanta : llantas_finales) {
                llanta.setCadenaPosicion(posiciones);
            }
        }
        if (baterias_finales != null) {
            for (Bateria bateria : baterias_finales) {
                bateria.setCadenaPosicion(posiciones);
            }
        }
    }

    public boolean isPosiciones() {
        return posiciones;
    }

    public void setPosiciones(boolean posiciones) {
        this.posiciones = posiciones;
    }
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton btnGuardar;
    private javax.swing.JButton btnNeumaticos;
    private javax.swing.JButton btnPosiciones;
    private javax.swing.JPanel cotenedor;
    private com.toedter.calendar.JDateChooser dateFechaMontaje;
    private javax.swing.JButton jButton1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel4;
    private javax.swing.JLabel jLabel5;
    private javax.swing.JLabel jLabel6;
    private javax.swing.JLabel jLabel7;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel jPanel2;
    private javax.swing.JPanel jPanel3;
    private javax.swing.JPanel jPanel4;
    private javax.swing.JPanel jPanel5;
    private javax.swing.JPanel jPanel6;
    private javax.swing.JPanel jPanel7;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JScrollPane jScrollPane3;
    private javax.swing.JTabbedPane jTabbedPane1;
    private javax.swing.JTabbedPane jTabbedPane2;
    private javax.swing.JToolBar jToolBar1;
    private javax.swing.JPanel panelPatios;
    private javax.swing.JPanel panelPilotos;
    private javax.swing.JTable tablaBaterias;
    private javax.swing.JTable tablaLlantas;
    private javax.swing.JTextPane txpComentarios;
    private javax.swing.JTextField txtKilometraje;
    // End of variables declaration//GEN-END:variables
}
